package de.preamp.clients.java.net;

import java.io.IOException;

import net.roarsoftware.lastfm.Caller;
import net.roarsoftware.lastfm.scrobble.Scrobbler;
import net.roarsoftware.lastfm.scrobble.Source;

import org.springframework.stereotype.Service;

import de.preamp.clients.java.data.Track;
import de.preamp.clients.java.utils.AbstractPreferences;
import de.preamp.clients.java.utils.PreferencesInFile;

/**
 * A wrapper class for {@link Scrobbler}.
 * 
 * @author André Stannek
 * @since 2010-03-22
 * @version 2010-08-22
 */
@Service("lastFMScrobbler")
public class LastFmScrobbler
{
    /**
     * the actual scrobbler.
     */
    private final transient Scrobbler scrobbler;

    /**
     * Indicates if handshake is successful.
     */
    private transient boolean handshaked; // NOPMD

    /**
     * default constructor.
     */
    public LastFmScrobbler()
    {
	handshaked = true;
	Caller.getInstance().setUserAgent("pre");
	Caller.getInstance().setDebugMode(false);
	final AbstractPreferences prefs = PreferencesInFile.instance();
	scrobbler =
		Scrobbler.newScrobbler("pre", "0.1a", prefs.getLastfmUser());
	try
	{
	    scrobbler.handshake(new String(prefs.getLastfmPassword()))
		    .getMessage();
	}
	catch (final IOException e)
	{
	    handshaked = false;
	}
    }

    /**
     * Scrobbles a track as "nowPlaying".
     * 
     * @param track
     *            the track to scrobble
     * @throws ScrobblingException
     *             if scrobbling fails
     */
    public final void nowPlaying(final Track track) throws ScrobblingException
    {
	if (handshaked && PreferencesInFile.instance().isScrobblingEnabled())
	{
	    try
	    {
		scrobbler.nowPlaying(track.getArtist(), track.getTitle(),
			track.getAlbum(), track.getLength(), track.getTrack());
	    }
	    catch (final IOException e)
	    {
		throw new ScrobblingException(e);
	    }
	}
    }

    /**
     * Submits a track as "heard" to last.fm.
     * 
     * @param track
     *            the track to scrobble
     * @param starttime
     *            the time the playback of the track started as unix timestamp
     * @throws ScrobblingException
     *             if scrobbling fails
     */
    public final void submit(final Track track, final long starttime)
	    throws ScrobblingException
    {
	if (handshaked && PreferencesInFile.instance().isScrobblingEnabled())
	{
	    try
	    {
		scrobbler.submit(track.getArtist(), track.getTitle(),
			track.getAlbum(), track.getLength(), track.getTrack(),
			Source.USER, starttime);
	    }
	    catch (final IOException e)
	    {
		throw new ScrobblingException(e);
	    }
	}
    }

    /**
     * @author André Stannek
     * @since 2010-08-22
     * @version 2010-08-22
     */
    public static class ScrobblingException extends Exception
    {
	/**
	 * 
	 */
	private static final long serialVersionUID = -4157090483326779760L;

	/**
	 * Constructor delgation.
	 * 
	 * @param cause
	 *            cause
	 */
	public ScrobblingException(final Throwable cause)
	{
	    super("Scrobbling failed!", cause);
	}
    }
}
